package controllers

import (
	"fmt"
	"gitee.com/freedom_feel/gui-bos-api/cmd/initialize/client"
	"gitee.com/freedom_feel/gui-bos-api/cmd/logic"
	"gitee.com/freedom_feel/gui-bos-api/common"
	_type "gitee.com/freedom_feel/gui-bos-api/common/type"
	util "gitee.com/freedom_feel/gui-bos-api/common/utils"
	"gitee.com/freedom_feel/gui-bos-api/global"
	"gitee.com/freedom_feel/gui-bos-api/logs"
	"gitee.com/freedom_feel/gui-bos-api/models"
	"github.com/bytedance/sonic"
	"github.com/fatih/structs"
	"io"
	"math/rand"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/beego/beego/v2/core/validation"
	"github.com/dgrijalva/jwt-go/v4"
	"github.com/gin-gonic/gin"
)

// 商城首页
func MallHome(g *gin.Context) {
	g.File("./cmd/public/mall.html")
	return
}

func SystemMall(g *gin.Context) {
	g.File("./cmd/public/system_mall.html")
	return
}

func PdtDescription(g *gin.Context) {
	g.File("./cmd/public/ptddesc.html")
	return
}

func GetDtdDesc(g *gin.Context) {
	id := g.Query("id")
	logs.Info("+++++++++req:" + id)
	ptd, err := client.QueryPtd(id)
	if err != nil {
		common.FailError(g, err.Error())
		return
	}
	common.Success(g, "", ptd)
	return
}

// 登录页面
func DefaultPage(g *gin.Context) {
	if _, ok := common.VerifyCookie(g.Request.Cookies()); ok {
		g.Redirect(http.StatusFound, "/system/mall")
		common.GetUserIp(g)
	}
	g.File("./cmd/public/index.html")
	return
}

// 注册页面
func RegDefaultPage(g *gin.Context) {
	common.GetUserIp(g)
	g.File("./cmd/public/register.html")
	return
}

// 修改密码页面
func UpPwdDefaultPage(g *gin.Context) {
	common.GetUserIp(g)
	g.File("./cmd/public/update.html")
	return
}

// uploads
func Uploads(g *gin.Context) {
	common.GetUserIp(g)
	//g.File("./cmd/public/update.html")
	return
}

// 发起采集任务页面
func TaskHome(g *gin.Context) {
	common.GetUserIp(g)
	g.File("./cmd/public/collect.html")
	return
}

// 用户详情
func UserInfo(g *gin.Context) {
	//g.JSON(http.StatusOK, gin.H{
	//	"code":    -1,
	//	"message": "暂未开放,正在测试当中,敬请期待.",
	//	"data":    nil,
	//})
	g.File("./cmd/public/userinfo.html")
	return
}

func ProductCar(g *gin.Context) {
	//g.JSON(http.StatusOK, gin.H{
	//	"code":    -1,
	//	"message": "暂未开放,正在测试当中,敬请期待.",
	//	"data":    nil,
	//})
	g.File("./cmd/public/car.html")
	return
}

// Login/mobile
func MobileLogin(g *gin.Context) {
	// 定义一个结构体变量
	var req models.MobileLoginRequest
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	if req.Mobile == "" {
		common.BadRequest(g, _type.ErrMsg("手机号或邮箱不可以为空"))
		return
	}
	valid := validation.Validation{}
	valid.Required(req.Sms, "sms").Message("验证码不可以为空")
	var mobile, email *string
	if req.Mobile != "" {
		if strings.Contains(req.Mobile, "@") {
			valid.Email(req.Mobile, "email").Message("邮箱格式有误")
			email = &req.Mobile
		} else {
			valid.Mobile(req.Mobile, "mobile").Message("手机号格式有误")
			mobile = &req.Mobile
		}
	}
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}
	//校验 验证码
	//codeKey := string(global.TimeoutKey) + req.Mobile
	code := client.GetRedisCode(_type.StrPinJie(string(global.TimeoutKey) + req.Mobile))
	if code != req.Sms {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}

	var cookie string
	var user models.User
	var err error
	user, err = client.UserLoginByMobile(req.Mobile)
	if err != nil {
		//5.21 新增 不存在不提示 直接注册
		if strings.Contains(err.Error(), "不存在") {
			//var nickname string
			// 如果email为空，设置为NULL而不是空字符串
			//if email != nil {
			//	nickname = *email
			//}
			//if mobile != nil {
			//	nickname = *mobile
			//}
			var randomString string
			for {
				randomString = common.RandomString(11)
				if !common.StartsWithZero(randomString) && randomString != "" {
					break
				}
			}
			//密文 存储
			pwd, e := util.Encrypt(global.PwdKeyNew, "Aa666888.")
			if e != nil {
				logs.Error(e.Error())
				common.FailError(g, e.Error())
				return
			}
			err = client.UserInsert(req.Mobile, &models.User{
				UserId:       uint(common.StrToInt(common.RandomString(10))),
				Username:     randomString,
				Password:     pwd,
				Mobile:       mobile,
				AuthStatus:   "0",
				UserIntegral: 0,
				UserBalance:  0,
				UserAvatar:   global.DefaultAvatar,
				Email:        email,
				Nickname:     common.RandomUUIDStyleNickname(),
				DaysCount:    "1",
			})
			if err != nil {
				logs.Error(err.Error())
				common.FailError(g, err.Error())
				return
			}
			//获取用户数据
			u, _ := client.UserLoginByMobile(req.Mobile)
			userdataKey := common.IntToStr(int(u.UserId)) + global.UserDtaKey
			err = client.RedisSetUserData(userdataKey, u, global.ExpiresIn)
			if err != nil {
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
				common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
				return
			}
			//global.KEEPKey = userdataKey
			token := util.CreateToken(&util.MyCustomClaims{
				UserId: strconv.Itoa(int(u.UserId)),
				StandardClaims: jwt.StandardClaims{
					ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
				},
			})
			err = client.RdKeepToken(common.IntToStr(int(u.UserId))+global.TokenKey, token, global.ExpiresIn)
			if err != nil {
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
				common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
				return
			}
			cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
			logs.Info(cookie)
			// 转换为 map
			userMap := structs.Map(u)
			// 删除敏感字段
			common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
			g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
			common.Success(g, "", map[string]interface{}{"userdata": userMap})
			return
		}
		common.FailError(g, err.Error())
		return
	}
	//将用户信息 储存到redis 缓冲中
	Key := common.IntToStr(int(user.UserId)) + global.UserDtaKey
	err = client.RedisSetUserData(Key, user, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	//}
	//生成token
	token := util.CreateToken(&util.MyCustomClaims{
		UserId: strconv.Itoa(int(user.UserId)),
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
		},
	})
	//存一下 token
	err = client.RdKeepToken(strconv.Itoa(int(user.UserId))+global.TokenKey, token, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
	logs.Info(cookie)
	// 转换为 map
	userMap := structs.Map(user)
	// 删除敏感字段
	common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
	g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
	common.Success(g, "", map[string]interface{}{"userdata": userMap})
	return
}

func MobileLogin1(g *gin.Context) {
	// 定义一个结构体变量
	var req models.MobileLoginRequest
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	if req.Mobile == "" {
		common.BadRequest(g, _type.ErrMsg("手机号或邮箱不可以为空"))
		return
	}
	valid := validation.Validation{}
	valid.Required(req.Sms, "sms").Message("验证码不可以为空")
	var mobile, email *string
	if req.Mobile != "" {
		if strings.Contains(req.Mobile, "@") {
			valid.Email(req.Mobile, "email").Message("邮箱格式有误")
			email = &req.Mobile
		} else {
			valid.Mobile(req.Mobile, "mobile").Message("手机号格式有误")
			mobile = &req.Mobile
		}
	}
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}
	//校验 验证码
	//codeKey := string(global.TimeoutKey) + req.Mobile
	code := client.GetRedisCode(_type.StrPinJie(string(global.TimeoutKey) + req.Mobile))
	if code != req.Sms {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}

	var cookie string
	var user models.User
	var err error
	user, err = client.UserLoginByMobile(req.Mobile)
	if err != nil {
		//5.21 新增 不存在不提示 直接注册
		if strings.Contains(err.Error(), "不存在") {
			//var nickname string
			// 如果email为空，设置为NULL而不是空字符串
			//if email != nil {
			//	nickname = *email
			//}
			//if mobile != nil {
			//	nickname = *mobile
			//}
			var randomString string
			for {
				randomString = common.RandomString(11)
				if !common.StartsWithZero(randomString) && randomString != "" {
					break
				}
			}
			//密文 存储
			pwd, e := util.Encrypt(global.PwdKeyNew, "Aa666888.")
			if e != nil {
				logs.Error(e.Error())
				common.FailError(g, e.Error())
				return
			}
			err = client.UserInsert(req.Mobile, &models.User{
				UserId:       uint(common.StrToInt(common.RandomString(10))),
				Username:     randomString,
				Password:     pwd,
				Mobile:       mobile,
				AuthStatus:   "0",
				UserIntegral: 0,
				UserBalance:  0,
				UserAvatar:   global.DefaultAvatar,
				Email:        email,
				Nickname:     common.RandomUUIDStyleNickname(),
				DaysCount:    "1",
			})
			if err != nil {
				logs.Error(err.Error())
				common.FailError(g, err.Error())
				return
			}
			//获取用户数据
			u, _ := client.UserLoginByMobile(req.Mobile)
			userdataKey := common.IntToStr(int(u.UserId)) + global.UserDtaKey
			err = client.RedisSetUserData(userdataKey, u, global.ExpiresIn)
			if err != nil {
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
				common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
				return
			}
			//global.KEEPKey = userdataKey
			token := util.CreateToken(&util.MyCustomClaims{
				UserId: strconv.Itoa(int(u.UserId)),
				StandardClaims: jwt.StandardClaims{
					ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
				},
			})
			err = client.RdKeepToken(common.IntToStr(int(u.UserId))+global.TokenKey, token, global.ExpiresIn)
			if err != nil {
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
				common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
				return
			}
			cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
			logs.Info(cookie)
			// 转换为 map
			userMap := structs.Map(u)
			// 删除敏感字段
			common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
			g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
			common.Success(g, "", map[string]interface{}{"userdata": userMap})
			return
		}
		common.FailError(g, err.Error())
		return
	}
	//将用户信息 储存到redis 缓冲中
	Key := common.IntToStr(int(user.UserId)) + global.UserDtaKey
	err = client.RedisSetUserData(Key, user, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	//}
	//生成token
	token := util.CreateToken(&util.MyCustomClaims{
		UserId: strconv.Itoa(int(user.UserId)),
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
		},
	})
	//存一下 token
	err = client.RdKeepToken(strconv.Itoa(int(user.UserId))+global.TokenKey, token, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
	logs.Info(cookie)
	// 转换为 map
	userMap := structs.Map(user)
	// 删除敏感字段
	common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
	g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
	common.Success(g, "", map[string]interface{}{"userdata": userMap})
	return
}

func Login(g *gin.Context) {
	// 定义一个结构体变量
	var req models.MobileLoginRequest
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	if req.Mobile == "" {
		common.BadRequest(g, _type.ErrMsg("手机号或邮箱不可以为空"))
		return
	}
	valid := validation.Validation{}
	valid.Required(req.Sms, "sms").Message("验证码不可以为空")
	var mobile, email *string
	if req.Mobile != "" {
		if strings.Contains(req.Mobile, "@") {
			valid.Email(req.Mobile, "email").Message("邮箱格式有误")
			email = &req.Mobile
		} else {
			valid.Mobile(req.Mobile, "mobile").Message("手机号格式有误")
			mobile = &req.Mobile
		}
	}
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}
	//校验 验证码
	//codeKey := string(global.TimeoutKey) + req.Mobile
	code := client.GetRedisCode(_type.StrPinJie(string(global.TimeoutKey) + req.Mobile))
	if code != req.Sms {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}

	var cookie string
	var user models.User
	var err error
	user, err = client.UserLoginByMobile(req.Mobile)
	if err != nil {
		//5.21 新增 不存在不提示 直接注册
		if strings.Contains(err.Error(), "不存在") {
			//var nickname string
			// 如果email为空，设置为NULL而不是空字符串
			//if email != nil {
			//	nickname = *email
			//}
			//if mobile != nil {
			//	nickname = *mobile
			//}
			var randomString string
			for {
				randomString = common.RandomString(11)
				if !common.StartsWithZero(randomString) && randomString != "" {
					break
				}
			}
			//密文 存储
			pwd, e := util.Encrypt(global.PwdKeyNew, "Aa666888.")
			if e != nil {
				logs.Error(e.Error())
				common.FailError(g, e.Error())
				return
			}
			err = client.UserInsert(req.Mobile, &models.User{
				UserId:       uint(common.StrToInt(common.RandomString(10))),
				Username:     randomString,
				Password:     pwd,
				Mobile:       mobile,
				AuthStatus:   "0",
				UserIntegral: 0,
				UserBalance:  0,
				UserAvatar:   global.DefaultAvatar,
				Email:        email,
				Nickname:     common.RandomUUIDStyleNickname(),
				DaysCount:    "1",
			})
			if err != nil {
				logs.Error(err.Error())
				common.FailError(g, err.Error())
				return
			}
			//获取用户数据
			u, _ := client.UserLoginByMobile(req.Mobile)
			userdataKey := common.IntToStr(int(u.UserId)) + global.UserDtaKey
			err = client.RedisSetUserData(userdataKey, u, global.ExpiresIn)
			if err != nil {
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
				common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
				return
			}

			//创建个 admin
			role := &models.Role{
				Name:        "admin",
				Description: "草鸡管理员",
				Users:       user.UserId,
				Permissions: "all",
			}
			err = client.CaveRole(strconv.Itoa(int(user.UserId)), role)
			if err != nil {
				common.FailErrCode(g, err.Error(), 200)
				return
			}

			//global.KEEPKey = userdataKey
			token := util.CreateToken(&util.MyCustomClaims{
				UserId: strconv.Itoa(int(u.UserId)),
				StandardClaims: jwt.StandardClaims{
					ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
				},
			})
			err = client.RdKeepToken(common.IntToStr(int(u.UserId))+global.TokenKey, token, global.ExpiresIn)
			if err != nil {
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
				common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
				return
			}
			cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
			logs.Info(cookie)
			// 转换为 map
			userMap := structs.Map(u)
			// 删除敏感字段
			common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
			g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
			common.Success(g, "", map[string]interface{}{"userdata": userMap})
			return
		}
		common.FailError(g, err.Error())
		return
	}
	//将用户信息 储存到redis 缓冲中
	Key := common.IntToStr(int(user.UserId)) + global.UserDtaKey
	err = client.RedisSetUserData(Key, user, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	//}

	//创建个 admin
	role := &models.Role{
		Name:        "admin",
		Description: "草鸡管理员",
		Users:       user.UserId,
		Permissions: "all",
	}
	err = client.CaveRole(strconv.Itoa(int(user.UserId)), role)
	if err != nil {
		common.FailErrCode(g, err.Error(), 200)
		return
	}

	//生成token
	token := util.CreateToken(&util.MyCustomClaims{
		UserId: strconv.Itoa(int(user.UserId)),
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
		},
	})
	//存一下 token
	err = client.RdKeepToken(strconv.Itoa(int(user.UserId))+global.TokenKey, token, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
	logs.Info(cookie)
	// 转换为 map
	userMap := structs.Map(user)
	// 删除敏感字段
	common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
	g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
	common.Success(g, "", map[string]interface{}{"userdata": userMap})
	return
}

// Login/up
func UserPwdLogin(g *gin.Context) {
	// 定义一个结构体变量
	var req models.UPLoginRequest
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	valid := validation.Validation{}
	valid.Required(req.Username, "username").Message("用户名不可以为空")
	valid.Required(req.Password, "password").Message("密码不可以为空")
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}

	var u models.User
	var cookie string
	userdata, err := client.RedisGet(_type.StrPinJie(req.Username, global.UserDtaKey))
	if err != nil {
		logs.Error(_type.ErrOther("redis data nil go query mysql").Msg)
	} else {
		sonic.Unmarshal([]byte(userdata), &u)
		logs.Info(userdata)
	}
	if u.UserId == 0 {
		u, err = client.UserLoginByUsername(req.Username, req.Password)
		if err != nil {
			if strings.Contains(err.Error(), "密码错误") {
				pwdKey := _type.StrPinJie(req.Username, "_", global.PwdCount)
				if client.RedisExist(pwdKey) {
					//这里暂时 忽略错误
					if get, _ := client.RedisGet(pwdKey); get == "5" {
						common.FailError(g, _type.ErrMsg("重试次数达到上线,请等到凌晨刷新").Msg)
						return
					}
				} else {
					//压入队列 (只压第一次) 后面清除用
					err1 := client.LPushList(global.PwdCount, pwdKey)
					if err1 != nil {
						logs.Error(err.Error())
						_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err1.Error()))
						common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
						return
					}
				}
				client.RedisIncr(pwdKey)
				common.FailError(g, _type.ErrMsg(err.Error()).Msg)
				return
			}
			common.FailError(g, _type.ErrMsg(err.Error()).Msg)
			return
		}
	}
	//将用户信息 储存到redis 缓冲中 说不定某个地方需要获取用户数据
	key := _type.StrPinJie(strconv.Itoa(int(u.UserId)), global.UserDtaKey)
	err = client.RedisSetUserData(key, u, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}

	//创建个 admin
	role := &models.Role{
		Name:        "admin",
		Description: "草鸡管理员",
		Users:       u.UserId,
		Permissions: "all",
	}
	err = client.CaveRole(strconv.Itoa(int(u.UserId)), role)
	if err != nil {
		common.FailErrCode(g, err.Error(), 200)
		return
	}

	//生成token
	token := util.CreateToken(&util.MyCustomClaims{
		UserId: strconv.Itoa(int(u.UserId)),
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
		},
	})
	//token 存一下
	err = client.RdKeepToken(_type.StrPinJie(strconv.Itoa(int(u.UserId)), global.TokenKey), token, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
	logs.Info(cookie)
	// 转换为 map
	userMap := structs.Map(u)
	// 删除敏感字段
	common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
	g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
	common.Success(g, "", map[string]interface{}{"userdata": userMap})
	return
}

func UserPwdLogin1(g *gin.Context) {
	// 定义一个结构体变量
	var req models.UPLoginRequest
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	valid := validation.Validation{}
	valid.Required(req.Username, "username").Message("用户名不可以为空")
	valid.Required(req.Password, "password").Message("密码不可以为空")
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}

	var u models.User
	var cookie string
	userdata, err := client.RedisGet(_type.StrPinJie(req.Username, global.UserDtaKey))
	if err != nil {
		logs.Error(_type.ErrOther("redis data nil go query mysql").Msg)
	} else {
		sonic.Unmarshal([]byte(userdata), &u)
		logs.Info(userdata)
	}
	if u.UserId == 0 {
		u, err = client.UserLoginByUsername(req.Username, req.Password)
		if err != nil {
			if strings.Contains(err.Error(), "密码错误") {
				pwdKey := _type.StrPinJie(req.Username, "_", global.PwdCount)
				if client.RedisExist(pwdKey) {
					//这里暂时 忽略错误
					if get, _ := client.RedisGet(pwdKey); get == "5" {
						common.FailError(g, _type.ErrMsg("重试次数达到上线,请等到凌晨刷新").Msg)
						return
					}
				} else {
					//压入队列 (只压第一次) 后面清除用
					err1 := client.LPushList(global.PwdCount, pwdKey)
					if err1 != nil {
						logs.Error(err.Error())
						_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err1.Error()))
						common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
						return
					}
				}
				client.RedisIncr(pwdKey)
				common.FailError(g, _type.ErrMsg(err.Error()).Msg)
				return
			}
			common.FailError(g, _type.ErrMsg(err.Error()).Msg)
			return
		}
	}
	//将用户信息 储存到redis 缓冲中 说不定某个地方需要获取用户数据
	key := _type.StrPinJie(strconv.Itoa(int(u.UserId)), global.UserDtaKey)
	err = client.RedisSetUserData(key, u, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}

	////创建个 admin
	//role := &models.Role{
	//	Name:        "admin",
	//	Description: "草鸡管理员",
	//	Users:       u.UserId,
	//	Permissions: "all",
	//}
	//err = client.CaveRole(strconv.Itoa(int(u.UserId)), role)
	//if err != nil {
	//	common.FailErrCode(g, err.Error(), 200)
	//	return
	//}

	//生成token
	token := util.CreateToken(&util.MyCustomClaims{
		UserId: strconv.Itoa(int(u.UserId)),
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
		},
	})
	//token 存一下
	err = client.RdKeepToken(_type.StrPinJie(strconv.Itoa(int(u.UserId)), global.TokenKey), token, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	cookie = common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
	logs.Info(cookie)
	// 转换为 map
	userMap := structs.Map(u)
	// 删除敏感字段
	common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
	g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
	common.Success(g, "", map[string]interface{}{"userdata": userMap})
	return
}

// Sendsms
func SendSms(g *gin.Context) {
	var req models.SendSmsRequest
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		g.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	valid := validation.Validation{}
	if req.Mobile == "" {
		common.BadRequest(g, _type.ErrMsg("手机号或邮箱不能为空"))
		return
	}
	if strings.Contains(req.Mobile, "@") {
		valid.Email(req.Mobile, "email").Message("邮箱格式有误")
	} else {
		valid.Mobile(req.Mobile, "mobile").Message("手机号格式有误")
	}
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}
	var err error
	//每日5次
	countKey := string(global.CountKey) + req.Mobile
	//压入队列 (只压次数) 后面清除用 不存在再压，避免重复删除
	if !client.RedisExist(string(global.CountKey) + req.Mobile) {
		err = client.LPushList(string(global.CountKey), string(global.CountKey)+req.Mobile)
	}
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	//五分钟有效
	timeoutKey := string(global.TimeoutKey) + req.Mobile
	if client.RedisExist(timeoutKey) {
		common.FailError(g, "请勿频繁发送.")
		return
	}
	//生成 验证码
	var code string
	for {
		code = common.RandomString(6)
		if !common.StartsWithZero(code) && code != "" {
			break
		}
	}
	if strings.Contains(req.Mobile, "@") {
		to := []string{req.Mobile}
		err = common.SendEmail(to, code, "")
	} else {
		//第三方...
		//if !client.IhuY(mobile, code) {
		//	c.Data["sonic"] = map[string]interface{}{
		//		"message": "调用第三方库失败",
		//		"modelss":   http.StatusAccepted,
		//	}
		//	c.ServeJSON()
		//}
	}
	if err != nil {
		logs.Error(err.Error())
		common.FailError(g, "验证码发送失败，请稍后重试")
		return
	}
	res, err := client.RedisGet(countKey)
	if err != nil && res != "" {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	if res == "5" {
		//global.MbChan = make(chan string, 10)
		//global.MbChan <- req.Mobile
		common.FailError(g, "今日验证码次数已用完,请等零点刷新.")
		return
	}
	global.MbChan = make(chan string, 10)
	global.MbChan <- req.Mobile
	//存入redis
	client.RedisIncr(countKey)
	err = client.RedisCodeTime(timeoutKey, code, 5)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	common.Success(g, "", map[string]interface{}{"smsCode": code, "id": rand.Intn(10)})
	return
}

// Register
func Register(g *gin.Context) {
	// 定义一个结构体变量
	var req models.RegRequest

	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	//验证 错误信息
	{
		valid := validation.Validation{}
		if req.Mobile == "" {
			common.BadRequest(g, _type.ErrMsg("手机号或邮箱不能为空"))
			return
		}
		if req.Mobile != "" {
			if strings.Contains(req.Mobile, "@") {
				valid.Email(req.Mobile, "email").Message("邮箱格式有误")
			} else {
				valid.Mobile(req.Mobile, "mobile").Message("手机号格式有误")
			}
		}
		if valid.HasErrors() {
			for _, v := range valid.Errors {
				common.BadRequest(g, v)
				return
			}
		}
	}
	var mobile, email *string
	if strings.Contains(req.Mobile, "@") {
		email = &req.Mobile
	} else {
		mobile = &req.Mobile
	}
	key := string(global.TimeoutKey) + req.Mobile
	code := client.GetRedisCode(key)
	if req.Sms != code || (code == "" || req.Sms == "") {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}
	u1, _ := client.UserLoginByMobile(req.Mobile)
	if u1.UserId != 0 {
		common.FailError(g, "邮箱或手机号已经存在,请核查!")
		return
	}
	var randomString string
	for {
		randomString = common.RandomString(11)
		if !common.StartsWithZero(randomString) && randomString != "" {
			break
		}
	}

	//密文 存储
	pwd, e := util.Encrypt(global.PwdKeyNew, req.Password)
	if e != nil {
		logs.Error(e.Error())
		common.FailError(g, e.Error())
		return
	}
	err := client.UserInsert(req.Mobile, &models.User{
		UserId:       uint(common.StrToInt(common.RandomString(10))),
		Username:     randomString,
		Password:     pwd,
		Mobile:       mobile,
		AuthStatus:   "0",
		UserIntegral: 0,
		UserBalance:  0,
		UserAvatar:   global.DefaultAvatar,
		Email:        email,
		Nickname:     req.Nickname,
		DaysCount:    "1",
	})
	if err != nil {
		logs.Error(err.Error())
		common.FailError(g, err.Error())
		return
	}
	//获取用户数据
	u, _ := client.UserLoginByMobile(req.Mobile)
	userdataKey := common.IntToStr(int(u.UserId)) + global.UserDtaKey
	err = client.RedisSetUserData(userdataKey, u, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	//创建个 admin
	role := &models.Role{
		Name:        "admin",
		Description: "草鸡管理员",
		Users:       u.UserId,
		Permissions: "all",
	}
	err = client.CaveRole(strconv.Itoa(int(u.UserId)), role)
	if err != nil {
		common.FailErrCode(g, err.Error(), 200)
		return
	}
	//global.KEEPKey = userdataKey
	token := util.CreateToken(&util.MyCustomClaims{
		UserId: strconv.Itoa(int(u.UserId)),
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
		},
	})
	err = client.RdKeepToken(strconv.Itoa(int(u.UserId))+global.TokenKey, token, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	cookie := common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
	logs.Info(cookie)
	// 转换为 map
	userMap := structs.Map(u)
	// 删除敏感字段
	common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
	g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
	common.Success(g, "", map[string]interface{}{"userdata": userMap})
	return
}

// Register
func Register1(g *gin.Context) {
	// 定义一个结构体变量
	var req models.RegRequest

	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	//验证 错误信息
	{
		valid := validation.Validation{}
		if req.Mobile == "" {
			common.BadRequest(g, _type.ErrMsg("手机号或邮箱不能为空"))
			return
		}
		if req.Mobile != "" {
			if strings.Contains(req.Mobile, "@") {
				valid.Email(req.Mobile, "email").Message("邮箱格式有误")
			} else {
				valid.Mobile(req.Mobile, "mobile").Message("手机号格式有误")
			}
		}
		if valid.HasErrors() {
			for _, v := range valid.Errors {
				common.BadRequest(g, v)
				return
			}
		}
	}
	var mobile, email *string
	if strings.Contains(req.Mobile, "@") {
		email = &req.Mobile
	} else {
		mobile = &req.Mobile
	}
	key := string(global.TimeoutKey) + req.Mobile
	code := client.GetRedisCode(key)
	if req.Sms != code || (code == "" || req.Sms == "") {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}
	u1, _ := client.UserLoginByMobile(req.Mobile)
	if u1.UserId != 0 {
		common.FailError(g, "邮箱或手机号已经存在,请核查!")
		return
	}
	var randomString string
	for {
		randomString = common.RandomString(11)
		if !common.StartsWithZero(randomString) && randomString != "" {
			break
		}
	}

	//密文 存储
	pwd, e := util.Encrypt(global.PwdKeyNew, req.Password)
	if e != nil {
		logs.Error(e.Error())
		common.FailError(g, e.Error())
		return
	}
	err := client.UserInsert(req.Mobile, &models.User{
		UserId:       uint(common.StrToInt(common.RandomString(10))),
		Username:     randomString,
		Password:     pwd,
		Mobile:       mobile,
		AuthStatus:   "0",
		UserIntegral: 0,
		UserBalance:  0,
		UserAvatar:   global.DefaultAvatar,
		Email:        email,
		Nickname:     req.Nickname,
		DaysCount:    "1",
	})
	if err != nil {
		logs.Error(err.Error())
		common.FailError(g, err.Error())
		return
	}
	//获取用户数据
	u, _ := client.UserLoginByMobile(req.Mobile)
	userdataKey := common.IntToStr(int(u.UserId)) + global.UserDtaKey
	err = client.RedisSetUserData(userdataKey, u, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	//创建个 admin
	//role := &models.Role{
	//	Name:        "admin",
	//	Description: "草鸡管理员",
	//	Users:       u.UserId,
	//	Permissions: "all",
	//}
	//err = client.CaveRole(strconv.Itoa(int(u.UserId)), role)
	//if err != nil {
	//	common.FailErrCode(g, err.Error(), 200)
	//	return
	//}
	//global.KEEPKey = userdataKey
	token := util.CreateToken(&util.MyCustomClaims{
		UserId: strconv.Itoa(int(u.UserId)),
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + global.ExpiresIn)),
		},
	})
	err = client.RdKeepToken(strconv.Itoa(int(u.UserId))+global.TokenKey, token, global.ExpiresIn)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
		common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
		return
	}
	cookie := common.RandomString(25) + "-" + token + "-" + common.RandomString(25)
	logs.Info(cookie)
	// 转换为 map
	userMap := structs.Map(u)
	// 删除敏感字段
	common.MapDelFiled(userMap, []string{"Password", "UserBalance", "UserIntegral", "UserPhoto", "UserPhoto", "AuthStatus", "Model"})
	g.SetCookie(global.CookieKey, cookie, global.ExpiresIn, "/", "", false, false)
	common.Success(g, "", map[string]interface{}{"userdata": userMap})
	return
}

// Register
func UpdatePwd(g *gin.Context) {
	// 定义一个结构体变量
	var req models.UpPwdRequest
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	if req.Mobile == "" {
		common.BadRequest(g, _type.ErrMsg("手机号或邮箱不可以为空"))
		return
	}
	valid := validation.Validation{}
	valid.Required(req.Username, "username").Message("用户名不可以为空")
	valid.Required(req.Password, "password").Message("密码不可以为空")
	valid.Required(req.Mobile, "mobile").Message("手机号不可以为空")
	valid.Required(req.Sms, "sms").Message("验证码不可以为空")
	if strings.Contains(req.Mobile, "@") {
		valid.Email(req.Mobile, "email").Message("邮箱或手机号格式有误")
	} else {
		valid.Mobile(req.Mobile, "mobile").Message("手机号或邮箱格式有误")
	}
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}
	//校验 验证码
	codeKey := string(global.TimeoutKey) + req.Mobile
	code := client.GetRedisCode(codeKey)
	if code != req.Sms {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}
	_, err := client.QueryUser(req.Username, req.Mobile)
	if err != nil {
		if strings.Contains(err.Error(), "不存在") {
			common.FailError(g, err.Error())
			return
		}
	}
	pwd, e := util.Encrypt(global.PwdKeyNew, req.Password)
	if e != nil {
		common.FailError(g, e.Error())
		return
	}
	err = client.UpdatePwd(req.Username, req.Mobile, pwd)
	if code != req.Sms {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}

	common.Success(g, "修改成功,请重新登陆", nil)
	return
}

func UpdatePwd1(g *gin.Context) {
	// 定义一个结构体变量
	var req models.UpPwdRequest1
	// 从请求体中解析 JSON 数据
	if err := g.ShouldBindJSON(&req); err != nil {
		// 如果解析失败，返回错误
		common.BadRequest(g, err)
		return
	}
	if req.Mobile == "" {
		common.BadRequest(g, _type.ErrMsg("手机号或邮箱不可以为空"))
		return
	}
	valid := validation.Validation{}
	//valid.Required(req.Username, "username").Message("用户名不可以为空")
	valid.Required(req.Password, "password").Message("密码不可以为空")
	valid.Required(req.Mobile, "mobile").Message("手机号不可以为空")
	valid.Required(req.Sms, "sms").Message("验证码不可以为空")
	if strings.Contains(req.Mobile, "@") {
		valid.Email(req.Mobile, "email").Message("邮箱或手机号格式有误")
	} else {
		valid.Mobile(req.Mobile, "mobile").Message("手机号或邮箱格式有误")
	}
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			common.BadRequest(g, v)
			return
		}
	}
	//校验 验证码
	codeKey := string(global.TimeoutKey) + req.Mobile
	code := client.GetRedisCode(codeKey)
	if code != req.Sms {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}
	_, err := client.QueryUser1(req.Mobile)
	if err != nil {
		if strings.Contains(err.Error(), "不存在") {
			common.FailError(g, err.Error())
			return
		}
	}
	pwd, e := util.Encrypt(global.PwdKeyNew, req.Password)
	if e != nil {
		common.FailError(g, e.Error())
		return
	}
	err = client.UpdatePwd1(req.Mobile, pwd)
	if code != req.Sms {
		common.FailError(g, "验证码有误，请按短信填写!")
		return
	}

	common.Success(g, "修改成功,请重新登陆", nil)
	return
}

// LoginOut
func LoginOut(g *gin.Context) {
	if uid, ok := common.VerifyCookie(g.Request.Cookies()); ok {
		userInfo, err := common.ByUidGetUserInfo(uid)
		if err != nil {
			logs.Error(err.Error())
			_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
			common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
			return
		}
		if !client.RedisDel(userInfo.Username + global.TokenKey) {
			logs.Error("删除失败")
		}
		if !client.RedisDel(uid + global.UserDtaKey) {
			logs.Error("删除失败")
		}
		logs.Info("删除成功")
		return
	}
}

// UploadAvatar
func UploadAvatar(g *gin.Context) {
	file, err := g.FormFile("avatar")
	if err != nil {
		logs.Error(err.Error())
		common.BadRequest(g, err)
		return
	}
	// 1.筛一下文件 并 构建根目录
	suffix := common.GetFileExtension(file.Filename, &common.FileExtensionOptions{WithDot: true, ToLower: true, MultipleDots: true})
	var src string
	switch suffix {
	case ".jpg", ".jpeg", ".png":
		// 验证文件名
		{
			if file.Filename == "" || strings.Contains(file.Filename, "/") || strings.Contains(file.Filename, "\\") {
				common.FailError(g, "文件名不合法")
				return
			}
			if file.Size > global.MaxFileSize*2.5 { // 5MB限制
				common.FailError(g, "文件大小不能超过5MB")
				return
			}

			if !strings.HasPrefix(file.Header.Get("Content-Type"), "image/") {
				common.FailError(g, "只允许上传图片文件")
				return
			}
		}
		src = global.UploadImgSrc
	case ".pdf", ".pdf.pdf":
		src = global.UploadPDFSrc
	case ".xlsx":
		src = global.UploadXlsxSrc
	default:
		src = global.UploadOtherSrc
	}
	// 2. 打开文件
	f, err := file.Open()
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,打开文件失败:%v", err.Error()))
		common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
		return
	}
	defer func(f multipart.File) {
		err = f.Close()
		if err != nil {

		}
	}(f)

	// 3. 读取文件内容
	fileBytes, err := io.ReadAll(f)
	if err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,文件读取失败:%v", err.Error()))
		common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
		return
	}

	//输出路径
	uploadDir := filepath.Join("./", src)
	if !common.PathExists(uploadDir) {
		if err = os.MkdirAll(uploadDir, 0755); err != nil {
			logs.Error(err.Error())
			_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,创建目录失败:%v", err.Error()))
			common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
			return
		}
	}

	//文件名 自定义
	var filename string
	filename = time.Now().Format("20060102150405")
	if len(file.Filename) > 5 {
		filename += common.RandomString(10) + suffix
	} else {
		filename += filepath.Ext(file.Filename)
	}

	// 4. 构造完整文件路径
	filePath := filepath.Join(uploadDir, filename)
	//最终路径
	path := src + filename

	// 5. 写入文件
	if err = os.WriteFile(filePath, fileBytes, 0644); err != nil {
		logs.Error(err.Error())
		_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,文件保存失败:%v", err.Error()))
		common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
		return
	}

	//暂时 这样写 img（头像） 才去操作库 其余 可以直接返回
	if src == global.UploadImgSrc {
		//6.入库更改 路径
		if global.Uid != "" {
			//更改用户表
			if err = client.UpdateUserPhoto(global.Uid, path); err != nil {
				os.Remove(filePath)
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,更改用户表:%v", err.Error()))
				common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
				return
			}
			//查询所有历史
			history, err1 := client.GetHistory(global.Uid)
			if err1 != nil {
				os.Remove(filePath)
				logs.Error(err1.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,查询所有历史:%v", err1.Error()))
				common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
				return
			}
			//更改状态 为0
			for _, v := range history {
				err = client.UpdateHistory(v.UserId)
				if err != nil {
					os.Remove(filePath)
					logs.Error(err.Error())
					_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,更改状态:%v", err.Error()))
					common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
					return
				}
			}
			//再插入一条最新的
			if err = client.SaveHistory(models.PhotoHistory{
				UserId:    global.Uid,
				NewAvatar: path,
				IsNew:     "1",
			}); err != nil {
				os.Remove(filePath)
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,插入:%v", err.Error()))
				common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
				return
			}

			userdataKey := global.Uid + global.UserDtaKey
			//更新缓存
			var res string
			res, err = client.RedisGet(userdataKey)
			if err != nil {
				os.Remove(filePath)
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,更新缓存:%v", err.Error()))
				common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
				return
			}
			var userInfo models.User
			sonic.Unmarshal([]byte(res), &userInfo)
			userInfo.UserAvatar = path
			//保持 时间不变
			err = client.RedisSetKeepTTL(userdataKey, userInfo)
			if err != nil {
				os.Remove(filePath)
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误,更新缓存keepTTL:%v", err.Error()))
				common.FailErrCode(g, "上传服务异常,请稍后重试.", http.StatusInternalServerError)
				return
			}
		}
	}
	// 7. 返回成功响应
	common.Success(g, "", path)
	return
}

func CheckLogin(g *gin.Context) {
	if uid, ok := common.VerifyCookie(g.Request.Cookies()); ok {
		// 如果认证通过，继续处理请求
		g.Next()
		common.GetUserIp(g)
		global.Uid = uid
		common.Success(g, "", true)
		return
	}
	common.Success(g, "", false)
	return
}

func AddAdmin(g *gin.Context) {
	uid := global.Uid
	role := &models.Role{
		Name:        "admin",
		Description: "草鸡管理员",
		Users:       uint(common.StrToInt(uid)),
		Permissions: "all",
	}
	err := client.CaveRole(uid, role)
	if err != nil {
		common.FailErrCode(g, err.Error(), 200)
		return
	}
	common.Success(g, "", false)
	return
}

func GetUserInfo(g *gin.Context) {
	if global.Uid != "" {
		//if uid, exist := g.Get("u-id"); exist {
		//if uid, ok := common.VerifyCookie(g.Request.Cookies()); ok {
		userInfo, err := common.ByUidGetUserInfo(global.Uid)
		if err != nil {
			logs.Error(err.Error())
			_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
			common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
			return
		}
		decrypt, err := util.Decrypt(global.PwdKeyNew, userInfo.Password)
		if err != nil {
			logs.Error(err.Error())
			_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
			common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
			return
		}
		if decrypt != "Aa666888." {
			decrypt = ""
		}
		var role string
		if client.IsAdmin(userInfo.UserId) {
			role = "super_admin"
		} else {
			role = "user"
		}

		common.Success(g, "", map[string]interface{}{
			"UserNick":      userInfo.Nickname,
			"UserName":      userInfo.Username,
			"UserPwd":       decrypt,
			"DaysCount":     userInfo.DaysCount,
			"UserAvatar":    userInfo.UserAvatar,
			"DetailRegDate": userInfo.CreatedAt.Format("2006-01-02"),
			"UserBalance":   userInfo.UserBalance,
			"UserRole":      role,
		})
		return
	}
}

// 获取地区数据
func GetAreaData(g *gin.Context) {
	var a models.PmArea
	if err := g.BindJSON(&a); err != nil {
		common.BadRequest(g, err)
		return
	}
	data, err := logic.FindAllData(a.Address)
	if err != nil {
		common.BadRequest(g, err)
		return
	}
	common.Success(g, "数据获取成功", data)
	return
}

// 获取地区数据 （携带rod）
func GetCityData(g *gin.Context) {
	if global.Uid != "" {
		var cd models.PmCityDB
		if err := g.BindJSON(&cd); err != nil {
			common.BadRequest(g, err)
			return
		}
		//global.IsDB = &cd.IsDB
		//if cd.IsDB == "true" {
		//var (
		//	MysqlErr error
		//	RedisErr error
		//)
		//global.DB, MysqlErr = client.InitMysql()
		//if MysqlErr != nil {
		//	common.Success(g, map[string]interface{}{"message": MysqlErr.Error(), "code": -1, "data": nil})
		//	return
		//}
		//global.Rdb, RedisErr = client.InitRedis()
		//if RedisErr != nil {
		//	common.Success(g, map[string]interface{}{"message": RedisErr.Error(), "code": -1, "data": nil})
		//	return
		//}
		//} else {
		//	err := common.ParseSQLToMap("area.sql")
		//	if err != nil {
		//		common.Success(g, map[string]interface{}{"message": err.Error(), "code": -1, "data": nil})
		//		return
		//	}
		//}
		err, i, b := logic.GetData(cd)
		if err != nil {
			common.FailError(g, err.Error())
			return
		}
		if i != nil {
			logs.Info(fmt.Sprintf("调试 - i 的类型: %T, ", i)) // 重要调试信息
			if value, ok := i.([]models.SelectBoss); ok {
				global.DataKey = _type.StrPinJie(cd.WorkCity + cd.WorkType)
				if !client.RedisExist(global.Uid + "_" + global.DataKey) {
					client.RedisSet(global.Uid+"_"+global.DataKey, value)
				}
				common.Success(g, "数据存在,可直接查看", nil)
				return
			}
		}
		if !b {
			logs.Info("压入队列")
			// 添加元素到有序集合
			marshal, _ := sonic.Marshal(cd)
			err = client.AddToZSetWithDefaultScore(global.My_zset, string(marshal))
			if err != nil {
				logs.Error(err.Error())
				_type.ErrChan <- *_type.ErrSystem(fmt.Sprintf("系统内部错误:%v", err.Error()))
				common.FailErrCode(g, "系统内部错误,请稍后再试.", http.StatusInternalServerError)
				return
			}
			common.Success(g, "数据需重新采集，请等待", nil)
			return
		}
	}
}

// 获取地区数据 （携带rod）
func SetScore(g *gin.Context) {
	var cd models.PmSetScore
	if err := g.BindJSON(&cd); err != nil {
		common.BadRequest(g, err)
		return
	}
	js, _ := sonic.Marshal(cd)
	var pm models.PmCityDB
	sonic.Unmarshal(js, &pm)
	jspm, _ := sonic.Marshal(pm)
	err := client.AddToZSet(global.My_zset, string(jspm), common.StrToFloat(cd.Score))
	if err != nil {
		fmt.Println("Failed to add task3:", err)
		return
	}
	common.Success(g, "", nil)
	return
}

// 删除数据
func DelBrandData(g *gin.Context) {
	var b models.PmBrand
	if err := g.BindJSON(&b); err != nil {
		common.BadRequest(g, err)
		return
	}
	if logic.Del(b.BrandName) {
		common.Success(g, "删除成功", nil)
		return
	} else {
		common.Success(g, "删除失败", nil)
		return
	}

}

// 获取 任务
func QueryTask(g *gin.Context) {
	var t models.PmTask
	if err := g.BindJSON(&t); err != nil {
		common.BadRequest(g, err)
		return
	}
	logs.Info("参数：" + t.TaskName + t.TaskKey)
	res, err := logic.QueryTasks(t.TaskName, t.TaskKey)
	data, _ := sonic.Marshal(res)
	logs.Info("请求成功：[data]" + string(data))
	if err != nil || res.TaskName == "" {
		common.FailError(g, "查询错误或者无此任务")
		return
	} else {
		common.Success(g, "", res)
		return
	}

}

// 获取 任务
func CreatTask(g *gin.Context) {
	var t models.PmTask
	if err := g.BindJSON(&t); err != nil {
		common.BadRequest(g, err)
		return
	}
	common.Success(g, "暂未开放,请耐心等待", nil)
	return
}

// 获取 任务
func GetTask(g *gin.Context) {
	common.Success(g, "暂未开放,请耐心等待", nil)
	return
	var t models.PmTask
	if err := g.BindJSON(&t); err != nil {
		common.BadRequest(g, err)
		return
	}
	// 获取有序集合中的元素（按优先级升序）
	tasks, err := client.GetZSetRange(global.My_zset, 0, -1)
	if err != nil {
		fmt.Println("Failed to get tasks:", err)
		return
	}

	var cb models.PmCityDB
	for _, v := range tasks {
		sonic.Unmarshal([]byte(v), &cb)
	}
	_, _, _ = logic.FindOne(cb)
	common.Success(g, "暂未开放,请耐心等待", nil)
	return
}

// 结束 任务
func EndTask(g *gin.Context) {
	var t models.PmTask
	if err := g.BindJSON(&t); err != nil {
		common.BadRequest(g, err)
		return
	}
	common.Success(g, "暂未开放,请耐心等待", nil)
	return
	endTask, err := logic.EndTasks(t.TaskName, t.TaskKey)
	if err != nil {
		common.FailError(g, err.Error())
	}
	fmt.Println(endTask)
	//if controllers.QueryTask(db, t.TaskName) {
	common.Success(g, "任务结束成功", nil)
	return

}

// 获取 任务
func Notify(g *gin.Context) {
	var t models.PmTask
	if err := g.BindJSON(&t); err != nil {
		common.BadRequest(g, err)
		return
	}
	common.Success(g, "暂未开放,请耐心等待", nil)
	return
}

// 添加地区 code
func InsertArea(g *gin.Context) {
	//var ct modelss.PmCity
	// 尝试将JSON绑定到form变量
	cityName := g.Query("cityName")
	cityCode := g.Query("cityCode")
	//if err := g.BindJSON(&ct); err != nil {
	//	common.Success(g, map[string]interface{}{"message": err.Error(), "code": -1})
	//	return
	//}
	err := logic.InsertCity(cityName, cityCode)
	if err != nil {
		common.FailError(g, err.Error())
		return
	}
	common.Success(g, "任务添加成功", nil)
	return
}

func PdtList(g *gin.Context) {
	product, err := client.FindAllProduct()
	if err != nil {
		common.BadRequest(g, err)
		return
	}
	logs.Info("请求成功 - product -返回数据")
	common.Success(g, "", product)
	return
}

func PdtCgyList(g *gin.Context) {
	product, err := client.FindAllProductCategory()
	if err != nil {
		common.BadRequest(g, err)
		return
	}
	logs.Info("请求成功 - ProductCategory -返回数据")
	common.Success(g, "", product)
	return
}

func PdtHostList(g *gin.Context) {
	product, err := client.FindAllHotProduct()
	if err != nil {
		common.BadRequest(g, err)
		return
	}
	logs.Info("请求成功 - HotProduct -返回数据")
	common.Success(g, "", product)
	return
}
